package it;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Properties;

public class ExtractionUtility {

	public static String SEPARATOR = ";";
	public static String INPUT_FOLDER = ".\\..\\input\\";
	//public static String INPUT_FOLDER = "";
	public static String OUTPUT_FOLDER = ".\\..\\output\\";
	//public static String OUTPUT_FOLDER = "";
	public static String STATISTICAL_FILE = "Statistica Officina";
	public static String WORKER_TIME_FILE = "Produttivit"; 
	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) {
		String filename = args[0];
		System.out.println("Inizio elaborazione del file " + filename + ".txt");
		BufferedReader br = null;
		Properties carProp = null;
		PrintWriter outPutFile = null;
		try {
			br = new BufferedReader(new FileReader(INPUT_FOLDER + filename + ".txt"));
			carProp = new Properties();
			carProp.load(new FileInputStream("Dictionary.properties"));
			outPutFile = new PrintWriter(OUTPUT_FOLDER + filename+".csv");
		} catch (FileNotFoundException e) {
			System.out.println("Non ho trovato il file " + filename + ".txt, oppure è attualmente in uso");
			System.exit(1);
		} catch (IOException e) {
			System.out.println("Ho avuto un errore nella lettura del file " + filename + ".txt");
			System.exit(1);
		}
	    try {
	        StringBuffer sb = new StringBuffer();
	        String line = br.readLine();
	        if (line.startsWith(STATISTICAL_FILE)){
	        	System.out.println("Il file che ho individuato è di tipo statistico ");
		        boolean firstLine = true;
		        boolean firstPrintLine = false;
		        boolean wrongClientName = false;
		        while (line != null) {
		        	sb.append(line).append(SEPARATOR);
		        	boolean c = line.matches("\\s+(P|0)[0-9]{5}\\s+.*");
		        	if (c){
		        		if (firstLine){
		        			wrongClientName = parseAndPrintString(line.trim(), true, carProp, outPutFile);
		        			firstPrintLine = true;
		        		}
		        		String esito = sb.toString().trim();
		        		String[] elenco = esito.split(SEPARATOR);
		        		boolean found = false;
		        		for (int i = elenco.length - 1; i >= 0; i--) {
							String string = elenco[i];
							if (string.matches("(\\s+(-|[0-9]|,|\\.)+){1,4}")){
								found = true;
								printTotal(string, outPutFile, wrongClientName);
								break;
							}
						}
		        		if (!found && firstPrintLine)
		        			outPutFile.println(SEPARATOR+"0"+SEPARATOR+"0"+SEPARATOR+"0"+SEPARATOR+"0");
		        		if (!firstLine){
		        			wrongClientName = parseAndPrintString(line.trim(), false, carProp, outPutFile);
		        		}
		        		sb.setLength(0);
		        	}
		            line = br.readLine();
		            firstLine = false;
		        }
		        // Gestione ultima riga
		        String esito = sb.toString().trim();
	    		String[] elenco = esito.split(SEPARATOR);	 
	    		boolean found = false;
	    		boolean markerFound = false;
	    		for (int i = elenco.length - 1; i >= 0; i--) {
	    			if (elenco[i].contains("Totali generali:")){
	    				markerFound = true;
	    			}
					String string = elenco[i];
					if (markerFound && string.matches("(\\s+(-|[0-9]|,|\\.)+){1,4}")){
						found = true;
						printTotal(string, outPutFile, wrongClientName);
						break;
					}    			
	    		}
	    		if (!found)
	    			outPutFile.println(SEPARATOR+"0"+SEPARATOR+"0"+SEPARATOR+"0"+SEPARATOR+"0");   
	        }
	        else if (line.startsWith(WORKER_TIME_FILE)){
	        	String workerName = "";
	        	StringBuffer finalRow = new StringBuffer();
	        	boolean isRowTerminated = false;
	        	 while (line != null) {
	        		 sb.append(line).append(SEPARATOR);
	        		 if (line.contains("Operaio :")){
	        			 String[] nomeOperaio = line.split(":");
	        			 workerName = nomeOperaio[1].trim();
	        		 }
	        		 String[] rowSplitted = line.split("\\s+"); 
	        		 if (rowSplitted.length == 5 && line.matches("((\\d{1,2}[.]\\d{2}[.]\\d{2})\\s*){2}.*")){
	        			 finalRow.append(workerName).append(SEPARATOR).append(rowSplitted[2]).append(SEPARATOR).append(rowSplitted[3]).append(SEPARATOR).append(rowSplitted[4]).append(SEPARATOR);
	        			 isRowTerminated = true;
	        		 }
	        		 if (isRowTerminated){
	        			 outPutFile.println(finalRow.toString());
	        			 isRowTerminated = false;
	        			 finalRow.setLength(0);
	        			 sb.setLength(0);
	        		 }
	        		 line = br.readLine();
	        	 }
	        }
	    } catch (IOException e) {
	    	System.out.println("Ho avuto un errore nella lettura del file " + filename + ".txt");
			System.exit(1);
		} finally {
	        try {
				br.close();
				outPutFile.close();
				carProp.store(new FileOutputStream("Dictionary.properties"), "");
			} catch (IOException e) {
				System.out.println("Ho avuto un errore nella chiusra del file " + filename + ".txt");
				System.exit(1);
			}
	        System.out.println("Elaborazione terminata. Prodotto il file " + filename+".xls");
	    }		
	    System.exit(0);
	}

	private static void printTotal(String string, PrintWriter outPutFile, boolean wrongClientName) throws NumberFormatException {
		String[] totali = string.trim().split("\\s+");
		if (totali.length == 1){
			outPutFile.print(SEPARATOR + totali[0].trim()+SEPARATOR+"0"+SEPARATOR+"0"+SEPARATOR+"0");
		}
		else if (totali.length == 2){
			outPutFile.print(SEPARATOR+"0"+SEPARATOR+"0"+SEPARATOR + totali[0].trim()+SEPARATOR+totali[1].trim());
		}
		else if (totali.length == 3){
			if (Double.parseDouble(totali[0].trim().replace(".", "").replace(",", ".")) > 100)
				outPutFile.print(SEPARATOR + totali[0].trim()+SEPARATOR+"0"+SEPARATOR+totali[1].trim()+SEPARATOR+totali[2].trim()+SEPARATOR+"DUBBIO");
			else
				outPutFile.print(SEPARATOR+"0"+SEPARATOR + totali[0].trim()+SEPARATOR+totali[1].trim()+SEPARATOR+totali[2].trim()+SEPARATOR+"DUBBIO");
		}								
		else{
			for (int j = 0; j < totali.length; j++) {
				String valore = totali[j];
				outPutFile.print(SEPARATOR + valore.trim());
			}
		}
		if (wrongClientName)
			outPutFile.print(SEPARATOR + "NOME DEL CLIENTE ERRATO");
		
		outPutFile.println();
	}
	
	private static boolean parseAndPrintString(String inStr, boolean newLine, Properties prop, PrintWriter outPutFile){
		boolean wrongClientName = false;
		String[] ret = inStr.split("\\s+");
		int index = inStr.indexOf(ret[3]);
		String res = inStr.substring(index);
		String[] listOfClients = res.split("\\s{2,}+");
		StringBuffer sbName = new StringBuffer(SEPARATOR);
		for (int i = 0; i < listOfClients.length; i++) {
			String propRes = (String)prop.get(listOfClients[i]);
			if (i == 0 && !"no".equalsIgnoreCase(propRes) && !"yes".equalsIgnoreCase(propRes)){
				System.out.print("Ooops..non ho trovato ["+listOfClients[i]+"] come macchina.\n"+inStr+"\nVuoi aggiungerla?[s/n]");
				BufferedReader readIn = new BufferedReader(new InputStreamReader(System.in));
				try {
					String response = readIn.readLine();
					if("s".equalsIgnoreCase(response)){
						prop.put(listOfClients[0], "no");
					}
					else{
						System.out.print("Vuoi inserire ["+listOfClients[i]+"] tra quelle valide?[s/n]");
						readIn = new BufferedReader(new InputStreamReader(System.in));
						response = readIn.readLine();
						if ("s".equalsIgnoreCase(response)){
							prop.put(listOfClients[0], "yes");
						}
						else{
							wrongClientName = true;
						}
					}
				} catch (IOException e) {

				}
			}
			if ("yes".equalsIgnoreCase(propRes) || !"no".equalsIgnoreCase(propRes))	
				sbName.append(listOfClients[i]).append(" ");
		}
		outPutFile.print(ret[0]+SEPARATOR+ret[1]+SEPARATOR+ret[2]+sbName.toString().trim());
		if (newLine)
			outPutFile.println();
		
		return wrongClientName;
	}

}
